﻿@namespace MudBlazor.Docs.Examples
@using System.ComponentModel.DataAnnotations

<MudGrid>
    <MudItem xs="12" sm="6" md="4">
        <EditForm EditContext="editContext1">
        <DataAnnotationsValidator />
            <MudAutocomplete Label="US States" @bind-Value="choice1.State" Required="true"
             SearchFunc="@SearchAsync" Immediate="true" CoerceValue="@coerceValue" ResetValueOnEmptyText="true"
             AdornmentIcon="@Icons.Material.Filled.Search" AdornmentColor="Color.Primary"
             For="@(() => choice1.State)"/>
            <MudButton ButtonType="ButtonType.Button" Variant="Variant.Filled" Color="Color.Primary" 
             Class="ml-auto mt-3 mb-3" OnClick="@(()=>success1=editContext1.Validate())">Validate</MudButton>
                   @if (success1)
                   {
                       <MudText Color="Color.Success">Success</MudText>
                   }
        </EditForm>
    </MudItem>
    <MudItem xs="12" sm="6" md="4">
        <EditForm EditContext="editContext2">
        <DataAnnotationsValidator />
            <MudAutocomplete Label="US States" @bind-Value="choice2.State" Required="true"
             SearchFunc="@SearchAsync" Immediate="true" CoerceValue="@coerceValue" ResetValueOnEmptyText="true"
             OpenIcon="@Icons.Material.Filled.Search" AdornmentColor="Color.Secondary"
             Validation="@(new Func<string, IEnumerable<string>>(Validate))" />
            <MudButton ButtonType="ButtonType.Button" Variant="Variant.Filled" Color="Color.Primary" 
                       Class="ml-auto mt-3 mb-3" OnClick="@(()=>success2=editContext2.Validate())">Validate</MudButton>
                   @if (success2)
                   {
                       <MudText Color="Color.Success">Success</MudText>
                   }
        </EditForm>
    </MudItem>
    <MudItem xs="12" sm="6" md="4">
        <MudForm @ref="form">
            <MudAutocomplete T="string" Label="US States" @bind-Value="choice3.State" Required="true"
             SearchFunc="@SearchAsync" Immediate="true" CoerceValue="@coerceValue" ResetValueOnEmptyText="true"
             CloseIcon="@Icons.Material.Filled.Search" AdornmentColor="Color.Tertiary"
             Validation="@(new Func<string, IEnumerable<string>>(Validate))" />
            <MudButton Variant="Variant.Filled" Color="Color.Primary" Class="ml-auto mt-3 mb-3" 
             OnClick="@(()=>form.Validate())">Validate</MudButton>
                    @if (form.IsTouched && form.IsValid)
                    {
                        <MudText Color="Color.Success">Success</MudText>
                    }
                    else
                    {
                        <MudText>IsTouched: @form.IsTouched, IsValid: @form.IsValid</MudText>
                    }
        </MudForm>
	</MudItem>
    <MudItem xs="12" md="12">
        <MudText Class="mb-n3" Typo="Typo.body2">
            <MudChip>@(choice1.State ?? "Not selected")</MudChip><MudChip>@(choice2.State ?? "Not selected")</MudChip><MudChip>@(choice3.State ?? "Not selected")</MudChip>
        </MudText>
    </MudItem>
    <MudItem xs="12" md="12" class="flex-column">
        <MudSwitch @bind-Checked="coerceValue" Color="Color.Tertiary">Coerce Value to Text (if not found)</MudSwitch>
    </MudItem>
</MudGrid>

@code {
    private MudForm form;
    private bool coerceValue;
    private bool success1;
    private bool success2;
    private Choice choice1 = new();
    private Choice choice2 = new();
    private Choice choice3 = new();
    private EditContext editContext1;
    private EditContext editContext2;

    protected override void OnInitialized()
    {
        editContext1 = new EditContext(choice1);
        editContext2 = new EditContext(choice2);
    } 

    private static string[] states =
    {
        "Alabama", "Alaska", "American Samoa", "Arizona",
        "Arkansas", "California", "Colorado", "Connecticut",
        "Delaware", "District of Columbia", "Federated States of Micronesia",
        "Florida", "Georgia", "Guam", "Hawaii", "Idaho",
        "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky",
        "Louisiana", "Maine", "Marshall Islands", "Maryland",
        "Massachusetts", "Michigan", "Minnesota", "Mississippi",
        "Missouri", "Montana", "Nebraska", "Nevada",
        "New Hampshire", "New Jersey", "New Mexico", "New York",
        "North Carolina", "North Dakota", "Northern Mariana Islands", "Ohio",
        "Oklahoma", "Oregon", "Palau", "Pennsylvania", "Puerto Rico",
        "Rhode Island", "South Carolina", "South Dakota", "Tennessee",
        "Texas", "Utah", "Vermont", "Virgin Island", "Virginia",
        "Washington", "West Virginia", "Wisconsin", "Wyoming",
    };

    private async Task<IEnumerable<string>> SearchAsync(string value)
    {
        // In real life use an asynchronous function for fetching data from an api.
        await Task.Delay(5);

        // if text is null or empty, show complete list
        if (string.IsNullOrEmpty(value))
        {
            return states;
        }

        return states.Where(x => x.Contains(value, StringComparison.InvariantCultureIgnoreCase));
    }

    private IEnumerable<string> Validate(string value)
    {        
        if (string.IsNullOrWhiteSpace(value))
        {
            yield return "The State field is required";
            yield break;
        }

        if (!states.Contains(value))
        {
            yield return "This is an incorrect value";
        }
    }

    public class Choice
    {
        [Required]
        [State]
        public string State { get; set;}
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter)]
    public sealed class StateAttribute : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (!states.Contains(value))
            {
                return new ValidationResult("This is an incorrect value", new[] { validationContext.MemberName });
            }

            return null;
        }
    }
}
